package com.xtaller.sdboot.config.aop;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.sdboot.utils.helper.JsonHelper;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author : Taller
 * @date : 2020/3/6 16:26
 * @Description :
 */
@Slf4j
@Aspect
@Component
public class HttpLogAspect {
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    ThreadLocal<JSONObject> logData = new ThreadLocal<>();

    @Pointcut("execution(public * com.xtaller.sdboot.controller.*.*(..))")
    public void httpLog(){}

    @Before("httpLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
        String method = request.getMethod();
        String path = request.getServletPath();
        var params = request.getParameterMap();
        var obj = JsonHelper.create().put("token", token)
                .put("method", method)
                .put("params", JsonHelper.o2s(params))
                .put("url", path)
                .put("ip", request.getRemoteAddr());
        logData.set(obj);
    }

    private final String METHOD = "method";
    private final String COMMON = "/common/";
    private final Integer SUCCESS = 200;

    @AfterReturning(returning = "ret", pointcut = "httpLog()")
    public void doAfterReturning(Object ret) {
        var obj = logData.get();
        var methods = Arrays.asList("put", "delete", "post");
        if(methods.contains(obj.getString(METHOD).toLowerCase())){
            var item = JsonHelper.o2j(ret).getJSONObject("body");
            var code = item.getInteger("code");
            Long time = System.currentTimeMillis() - startTime.get();
            if(code.equals(SUCCESS)) {
                var url = obj.getString("url");
                obj.put("time", time);
                if(url.indexOf(COMMON) < 0) {
                    // todo 写入日志
                    log.info("log", obj);
                    System.err.println("===aop log===");
                    System.err.println(JsonHelper.o2s(obj));
                }
            }
        }
    }
}
